import axios, {AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse} from "axios";
import {message} from "ant-design-vue";
import {HttpService} from "~/icesoft/utils/request/types";
import {baseUrl} from "~/config";
import {useUserStore} from "~/store/modulers/user";

const service: AxiosInstance = axios.create({
    baseURL: baseUrl,
    timeout: 30000
})

service.interceptors.request.use((config: any) => {
    return config
}, async (error: AxiosError) => {
    message.error(error.message);
    return Promise.reject(error)
});

service.interceptors.response.use((response: AxiosResponse) => {
    const {ok, code, message} = response.data;
    // 根据自定义错误码判断请求是否成功
    if (ok) {
        return response.data
    } else {
        // 处理业务错误。
        message.error(message)
        return Promise.reject(new Error(message))
    }
}, (error: AxiosError) => {
    // 处理 HTTP 网络错误
    let msg = ''
    // HTTP 状态码
    const status = error.response?.status
    switch (status) {
        case 401:
            msg = 'token 失效，请重新登录';
            useUserStore().logout();
            break;
        case 403:
            msg = '拒绝访问'
            break;
        case 404:
            msg = '请求地址错误'
            break;
        case 500:
            msg = '服务器故障'
            break;
        default:
            msg = '网络连接故障'
    }
    message.error(msg)
    return Promise.reject(error)
});

function setToken(canSet: boolean) {
    if (canSet && localStorage.getItem('token')) {
        service.defaults.headers["Authorization"] = "Bearer " + localStorage.getItem('token')
    }
}

export const http: HttpService = {

    get<T = any>(url: string, config?: AxiosRequestConfig, token: boolean = true): Promise<T> {
        setToken(token);
        return service.get(url, config)
    },

    post<T = any>(url: string, data?: object, config?: AxiosRequestConfig, token: boolean = true): Promise<T> {
        setToken(token);
        return service.post(url, data, config)
    },

    put<T = any>(url: string, data?: object, config?: AxiosRequestConfig, token: boolean = true): Promise<T> {
        setToken(token);
        return service.put(url, data, config)
    },

    delete<T = any>(url: string, config?: AxiosRequestConfig, token: boolean = true): Promise<T> {
        setToken(token);
        return service.delete(url, config)
    }

}
